#ifndef FACEGEOESTIMATION_H
#define FACEGEOESTIMATION_H
#include <QVector>
#include <QVector2D>
#include <QString>
#include <cv.hpp>
#include <QTextStream>
#include "pfmimage.h"
class FaceGeoEstimation
{
public:
    FaceGeoEstimation();
    ~FaceGeoEstimation();

    void Clear();
    void ReadTemplate(QString fileName);
    void ConstructPixelMatrix(QString imageFilePath, QVector<QString> imageFileNameList, QVector<short> imageIndexList);
    void InitialLightShapeEstimation(short singularNumber);
    void OutputReconstructFaceSVD(QString imageFilePath, QVector<QString> imageFileNameList);
    void FaceNormalEstimation(float threshold);
    void SetLogTextStream(QTextStream* p);
    void ReComputeLightMatrix();
    void ComputeAmbiguityMatrix();
    void SetShapeMatrixTemplate(cv::Mat shapeMatTemplate);
    void SetPixelMatrix(cv::Mat pm);

    cv::Mat GetShapematrixTemplate()
    {
        return shapeMatrixTemplate;
    }

    void ReadReferenceGeoImage(QString fileName);
    void ReconstructDepthMapByIntegration();
    cv::Mat DepthFromNormalByIntegration(cv::Mat normalMat);
    QVector3D ComputeGBRCofficient(cv::Mat depth);
    void SetGBRCofficient(QVector3D co);
    void OutputNormalMap(cv::Mat shapeMatrix4XN, QString fileName); //shapeMatrix4XN 4 rows N columns , N pixel num
    void OutputReconGeo(QString fileName);
    int GetPixelNum()
    {
        return pixelNum;
    }
    cv::Mat GetShapeMatrix()
    {
        return shapeMatrix;
    }
    cv::Mat GetDepthMatrix()
    {
        return depthMatrix;
    }
    void IterNumAdd()
    {
        iterNum++;
    }

private:


    QVector<short> SelectImagesForPixel(float threshold, int pixelIndex);
    void OutputMatrixToLog(cv::Mat cvMat, QString matName);//only support float type

private:
    QVector<QVector2D> pixelPosList;
    cv::Mat pixelMatrix;//
    cv::Mat lightMatrix; //
    cv::Mat shapeMatrix; //
    cv::Mat shapeMatrixTemplate;//
    cv::Mat depthMatrix;//
    cv::Mat singularMatrix;//
    cv::Mat ambiguityMatrix;//
    cv::Mat gbrMatrix;//

    int pixelNum;
    short imageNum;
    short singularNum;
    short imageWidth;
    short imageHeight;

    PFMImage templateImage;
    PFMImage referenceGeoImage;

    QTextStream* logTextStream;
    int iterNum;
};

#endif // FACEGEOESTIMATION_H
